package com.wpf.system.controller;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wpf.system.common.response.ResultUtils;
import com.wpf.system.common.response.ResultVO;
import com.wpf.system.common.utils.OrderDelayService;
import com.wpf.system.common.utils.RedisUtils;
import com.wpf.system.entity.*;
import com.wpf.system.entity.dto.OrdersDTO;
import com.wpf.system.entity.dto.OrdersSearchDTO;
import com.wpf.system.entity.vo.OrdersVO;
import com.wpf.system.entity.vo.PageVO;
import com.wpf.system.mapper.*;
import com.wpf.system.service.BalanceJournalService;
import com.wpf.system.service.OrdersService;
import com.wpf.system.service.PointJournalService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;


@RestController
@RequestMapping("/api/orders")
public class OrdersController {

    @Resource
    private OrdersService ordersService;

    @Resource
    private OrderDelayService orderDelayService;

    @Resource
    private FieldBookMapper fieldBookMapper;

    @Resource
    private EquipmentMapper equipmentMapper;

    @Resource
    private EquipmentRentMapper equipmentRentMapper;

    @Resource
    private EquipmentBuyMapper equipmentBuyMapper;

    @Resource
    private BalanceJournalService balanceJournalService;

    @Resource
    private PointJournalService pointJournalService;

    @Resource
    private RedisUtils redisUtils;

    @GetMapping
    public PageVO<OrdersVO> getUserOrders(
            @RequestParam(value = "uid",required=false) Long uid,
            @RequestParam(value = "no",required=false) String no,
            @RequestParam(value = "type",required=false) String type,
            @RequestParam(value = "startTime",required=false) String startTime,
            @RequestParam(value = "endTime",required=false) String endTime,
            @RequestParam(value = "page",required=false) int page,
            @RequestParam(value = "pageSize",required=false) int pageSize
    ){
        OrdersSearchDTO ordersSearchDTO = new OrdersSearchDTO();
        ordersSearchDTO.setUid(uid);
        ordersSearchDTO.setNo(no);
        ordersSearchDTO.setType(type);
        ordersSearchDTO.setStartTime(startTime);
        ordersSearchDTO.setEndTime(endTime);
        ordersSearchDTO.setPage(page);
        ordersSearchDTO.setPageSize(pageSize);
        return ordersService.getUserOrders(ordersSearchDTO);
    }

    @PostMapping
    public ResultVO addNewOrders(@RequestBody OrdersDTO ordersDTO){
        Orders orders = new Orders();
        String no = IdUtil.objectId();
        orders.setNo(no);
        orders.setUid(ordersDTO.getUid());
        orders.setCost(ordersDTO.getCost());
        orders.setPoint(ordersDTO.getPoint());
        orders.setType(ordersDTO.getType());
        Orders newOrders = ordersService.addNewOrders(orders,ordersDTO.getIid());
        if(ObjectUtil.isNotNull(newOrders)){
            orderDelayService.OrdersTimeBegin(no);
            return ResultUtils.success("下单成功！请在10分钟内支付！",newOrders);
        }else {
            return ResultUtils.error("下单失败！请检查订单内容！");
        }
    }

    @PostMapping("/recharge")
    public ResultVO addRechargeOrders(@RequestBody Orders orders){
        Orders newRechargeOrder = new Orders();
        newRechargeOrder.setNo(IdUtil.objectId());
        newRechargeOrder.setUid(orders.getUid());
        newRechargeOrder.setCost(orders.getCost());
        newRechargeOrder.setStatus(1);
        newRechargeOrder.setType(4);
        Orders newOrders = ordersService.addNewOrders(newRechargeOrder,null);
        if (ObjectUtil.isNotNull(newOrders)){
            return ResultUtils.success("充值成功！");
        }
        return ResultUtils.error("充值失败！");
    }

    @PutMapping
    public ResultVO payOrdersSuccess(@RequestBody Orders orders){
        if(orders.getType()==3){
            //原超时订单
            EquipmentRent equipmentRentOutTime =  equipmentRentMapper.selectOne(
                    new LambdaQueryWrapper<EquipmentRent>().eq(EquipmentRent::getOid, Convert.toLong(orders.getNo()))
            );
            orders.setNo(IdUtil.objectId());
            //超时订单支付
            Orders newOrders = ordersService.addNewOrders(orders,null);
            if(ordersService.payOrdersSuccess(newOrders)){
                equipmentRentOutTime.setStatus(10);
                equipmentRentMapper.updateById(equipmentRentOutTime);
                return ResultUtils.success("已支付超时费用！");
            }
            return ResultUtils.error("支付超时费用失败！");
        }else{
            if(ordersService.payOrdersSuccess(orders)){
                redisUtils.delZSet(OrderDelayService.ORDER_DELAY_TASK_KEY, orders.getNo());
                return ResultUtils.success("订单交易成功！");
            }
            return ResultUtils.error("订单交易失败！");
        }
    }

    @PutMapping("/cancel")
    public ResultVO cancelOrders(@RequestBody Orders orders){
        switch (orders.getType()){
            case 0:
                LambdaQueryWrapper<FieldBook> queryWrapper0 = new LambdaQueryWrapper<>();
                queryWrapper0.eq(FieldBook::getOid,orders.getId()).in(FieldBook::getStatus,0,1);
                List<FieldBook> fieldBookList = fieldBookMapper.selectList(queryWrapper0);
                fieldBookList.forEach(item->{
                    if(orders.getPoint()>0 || orders.getCost().compareTo(BigDecimal.valueOf(0))==1){
                        if(orders.getPoint()>0){
                            pointJournalService.pointInto(orders,0);
                        }
                        if(orders.getCost().compareTo(BigDecimal.valueOf(0))==1&&item.getStatus()!=0){
                            balanceJournalService.balanceInto(orders,0,item.getId());
                        }
                    }
                    item.setStatus(3);
                    fieldBookMapper.updateById(item);
                    //检查相同订单是否还有有效项，没有就关闭订单
                    LambdaQueryWrapper<FieldBook> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(FieldBook::getOid,orders.getId()).in(FieldBook::getStatus,0,1,2,6);
                    if(fieldBookMapper.selectCount(queryWrapper)==0){
                        orders.setStatus(2);
                        ordersService.updateById(orders);
                    }
                });
                break;
            case 1:
                LambdaQueryWrapper<EquipmentRent> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(EquipmentRent::getOid,orders.getId()).in(EquipmentRent::getStatus,0,1);
                List<EquipmentRent> equipmentRentList = equipmentRentMapper.selectList(queryWrapper1);
                equipmentRentList.forEach(item->{
                    if(orders.getPoint()>0 || orders.getCost().compareTo(BigDecimal.valueOf(0))==1){
                        if(orders.getPoint()>0){
                            pointJournalService.pointInto(orders,1);
                        }
                        if(orders.getCost().compareTo(BigDecimal.valueOf(0))==1&&item.getStatus()!=0){
                            balanceJournalService.balanceInto(orders,1,item.getId());
                        }
                    }
                    //退还库存
                    Equipment equipment = equipmentMapper.selectById(item.getEid());
                    equipment.setNumber(equipment.getNumber()+item.getNumber());
                    equipmentMapper.updateById(equipment);
                    item.setStatus(7);
                    equipmentRentMapper.updateById(item);
                    orders.setStatus(2);
                    ordersService.updateById(orders);
                });
                break;
            case 2:
                LambdaQueryWrapper<EquipmentBuy> queryWrapper2 = new LambdaQueryWrapper<>();
                queryWrapper2.eq(EquipmentBuy::getOid,orders.getId()).in(EquipmentBuy::getStatus,0,1);
                List<EquipmentBuy> equipmentBuyList = equipmentBuyMapper.selectList(queryWrapper2);
                equipmentBuyList.forEach(item->{
                    if(orders.getPoint()>0 || orders.getCost().compareTo(BigDecimal.valueOf(0))==1){
                        if(orders.getPoint()>0){
                            pointJournalService.pointInto(orders,2);
                        }
                        if(orders.getCost().compareTo(BigDecimal.valueOf(0))==1&&item.getStatus()!=0){
                            balanceJournalService.balanceInto(orders,2,item.getId());
                        }
                    }
                    //退还库存
                    Equipment equipment = equipmentMapper.selectById(item.getEid());
                    equipment.setNumber(equipment.getNumber()+item.getNumber());
                    equipmentMapper.updateById(equipment);
                    item.setStatus(7);
                    equipmentBuyMapper.updateById(item);
                    //检查相同订单是否还有有效项，没有就关闭订单
                    LambdaQueryWrapper<EquipmentBuy> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(EquipmentBuy::getOid,orders.getId()).in(EquipmentBuy::getStatus,0,1,2,5,6);
                    if(equipmentBuyMapper.selectCount(queryWrapper)==0){
                        orders.setStatus(2);
                        ordersService.updateById(orders);
                    }
                });
                break;
        }
        if(ordersService.getById(orders).getStatus()==2){
            return ResultUtils.success("取消订单成功！");
        }
        return ResultUtils.error("取消订单失败！");
    }

}
